import pygame
import math

# 定义颜色常量
BLACK = (0, 0, 0)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
WHITE = (255, 255, 255)
GRID_COLOR = (40, 40, 40)
LIGHT_GRAY = (200, 200, 200)
LIGHT_BLUE = (135, 206, 235)
YELLOW = (255, 255, 0)
DARK_GREEN = (0, 100, 0)
GOLD = (255, 215, 0)
PURPLE = (128, 0, 128)
CYAN = (0, 255, 255)
ORANGE = (255, 165, 0)
PINK = (255, 20, 147)
BLUE = (0, 0, 255)
DARK_BLUE = (0, 0, 139)
DARK_RED = (139, 0, 0)
DARK_PURPLE = (75, 0, 130)
DARK_CYAN = (0, 139, 139)

# 主题设置
THEMES = {
    "经典": {
        "background": (20, 20, 20),
        "grid": GRID_COLOR,
        "snake_head": YELLOW,
        "snake_tail": DARK_GREEN,
        "food": RED,
        "special_food": GOLD,
        "super_food": PURPLE,
        "obstacle": BLUE,
        "panel": BLACK,
        "border": LIGHT_GRAY
    },
    "深海": {
        "background": (5, 30, 50),
        "grid": (20, 60, 80),
        "snake_head": (0, 200, 255),
        "snake_tail": (0, 80, 120),
        "food": (255, 50, 50),
        "special_food": (255, 200, 50),
        "super_food": (255, 100, 255),
        "obstacle": (50, 100, 150),
        "panel": (10, 40, 60),
        "border": (30, 100, 150)
    },
    "森林": {
        "background": (10, 40, 10),
        "grid": (30, 70, 30),
        "snake_head": (200, 255, 0),
        "snake_tail": (20, 100, 0),
        "food": (255, 50, 0),
        "special_food": (255, 200, 0),
        "super_food": (200, 0, 200),
        "obstacle": (100, 70, 20),
        "panel": (20, 50, 20),
        "border": (50, 100, 50)
    },
    "霓虹": {
        "background": (10, 10, 25),
        "grid": (30, 30, 50),
        "snake_head": (0, 255, 255),
        "snake_tail": (200, 0, 200),
        "food": (255, 50, 150),
        "special_food": (255, 255, 0),
        "super_food": (50, 255, 50),
        "obstacle": (150, 50, 255),
        "panel": (20, 20, 40),
        "border": (100, 100, 200)
    }
}

def get_theme_colors(theme_name):
    """获取指定主题的颜色配置"""
    return THEMES.get(theme_name, THEMES["经典"])

def draw_snake(screen, snake, snake_pixels, direction, theme_colors, smooth_animation, active_effects, CELL_SIZE):
    """绘制贪吃蛇模型"""
    if not snake or len(snake_pixels) == 0:
        return
    
    # 如果启用平滑动画，使用像素坐标绘制
    if smooth_animation:
        draw_snake_smooth(screen, snake_pixels, direction, theme_colors, active_effects, CELL_SIZE)
    else:
        draw_snake_grid(screen, snake, direction, theme_colors, CELL_SIZE)

def draw_snake_smooth(screen, snake_pixels, direction, theme_colors, active_effects, CELL_SIZE):
    """使用平滑动画绘制蛇"""
    # 头部
    head_x, head_y = snake_pixels[0]
    head_rect = pygame.Rect(head_x, head_y, CELL_SIZE, CELL_SIZE)
    
    # 如果有双倍分数效果，添加金色光晕
    if "double" in active_effects:
        glow = pygame.Surface((CELL_SIZE*1.5, CELL_SIZE*1.5), pygame.SRCALPHA)
        glow_intensity = abs(math.sin(pygame.time.get_ticks() * 0.01)) * 100 + 50
        pygame.draw.ellipse(glow, (GOLD[0], GOLD[1], GOLD[2], glow_intensity), 
                         (0, 0, CELL_SIZE*1.5, CELL_SIZE*1.5))
        screen.blit(glow, (head_x - CELL_SIZE*0.25, head_y - CELL_SIZE*0.25))
    
    pygame.draw.rect(screen, theme_colors["snake_head"], head_rect, border_radius=5)  # 头部带圆角
    
    # 画眼睛
    draw_snake_eyes(screen, head_rect, direction, CELL_SIZE)
    
    # 蛇身 - 使用渐变颜色和像素坐标
    for i, pixel_pos in enumerate(snake_pixels[1:], 1):
        if i == len(snake_pixels) - 1:
            color = theme_colors["snake_tail"]  # 尾部保持深绿色
        else:
            # 计算渐变色
            ratio = i / len(snake_pixels)
            r = int(theme_colors["snake_head"][0] + (theme_colors["snake_tail"][0] - theme_colors["snake_head"][0]) * ratio)
            g = int(theme_colors["snake_head"][1] + (theme_colors["snake_tail"][1] - theme_colors["snake_head"][1]) * ratio)
            b = int(theme_colors["snake_head"][2] + (theme_colors["snake_tail"][2] - theme_colors["snake_head"][2]) * ratio)
            color = (r, g, b)
        
        # 根据节段位置绘制不同形状，使蛇看起来更平滑连贯
        radius = 3 if i < len(snake_pixels) - 1 else 5
        pygame.draw.rect(screen, color, (pixel_pos[0], pixel_pos[1], CELL_SIZE, CELL_SIZE), border_radius=radius)
        
        # 添加连接效果，使蛇身更连贯
        if i < len(snake_pixels) - 1:
            next_pos = snake_pixels[i+1]
            connect_x = (pixel_pos[0] + next_pos[0]) // 2 + CELL_SIZE // 4
            connect_y = (pixel_pos[1] + next_pos[1]) // 2 + CELL_SIZE // 4
            connect_rect = pygame.Rect(connect_x - CELL_SIZE//4, connect_y - CELL_SIZE//4, 
                                     CELL_SIZE//2, CELL_SIZE//2)
            pygame.draw.rect(screen, color, connect_rect, border_radius=2)

def draw_snake_grid(screen, snake, direction, theme_colors, CELL_SIZE):
    """使用网格坐标绘制蛇"""
    # 头部
    head = snake[0]
    head_rect = pygame.Rect(head[0] * CELL_SIZE, head[1] * CELL_SIZE, CELL_SIZE, CELL_SIZE)
    pygame.draw.rect(screen, theme_colors["snake_head"], head_rect, border_radius=5)  # 头部带圆角
    
    # 画眼睛
    draw_snake_eyes(screen, head_rect, direction, CELL_SIZE)
    
    # 蛇身 - 使用渐变颜色
    for i, segment in enumerate(snake[1:], 1):
        # 计算渐变颜色，从头部到尾部
        if i == len(snake) - 1:
            color = theme_colors["snake_tail"]  # 尾部保持深绿色
        else:
            # 计算渐变色
            ratio = i / len(snake)
            r = int(theme_colors["snake_head"][0] + (theme_colors["snake_tail"][0] - theme_colors["snake_head"][0]) * ratio)
            g = int(theme_colors["snake_head"][1] + (theme_colors["snake_tail"][1] - theme_colors["snake_head"][1]) * ratio)
            b = int(theme_colors["snake_head"][2] + (theme_colors["snake_tail"][2] - theme_colors["snake_head"][2]) * ratio)
            color = (r, g, b)
        pygame.draw.rect(screen, color, (segment[0] * CELL_SIZE, segment[1] * CELL_SIZE, CELL_SIZE, CELL_SIZE), border_radius=3)

def draw_snake_eyes(screen, head_rect, direction, CELL_SIZE):
    """绘制蛇的眼睛"""
    eye_radius = CELL_SIZE // 6
    eye_offset_x = CELL_SIZE // 4
    eye_offset_y = CELL_SIZE // 4
    
    # 根据方向调整眼睛位置
    if direction == (1, 0):  # 右
        eye1 = (head_rect.left + CELL_SIZE - eye_offset_x, head_rect.top + eye_offset_y)
        eye2 = (head_rect.left + CELL_SIZE - eye_offset_x, head_rect.top + CELL_SIZE - eye_offset_y)
    elif direction == (-1, 0):  # 左
        eye1 = (head_rect.left + eye_offset_x, head_rect.top + eye_offset_y)
        eye2 = (head_rect.left + eye_offset_x, head_rect.top + CELL_SIZE - eye_offset_y)
    elif direction == (0, 1):  # 下
        eye1 = (head_rect.left + eye_offset_x, head_rect.top + CELL_SIZE - eye_offset_y)
        eye2 = (head_rect.left + CELL_SIZE - eye_offset_x, head_rect.top + CELL_SIZE - eye_offset_y)
    else:  # 上
        eye1 = (head_rect.left + eye_offset_x, head_rect.top + eye_offset_y)
        eye2 = (head_rect.left + CELL_SIZE - eye_offset_x, head_rect.top + eye_offset_y)
    
    pygame.draw.circle(screen, BLACK, eye1, eye_radius)
    pygame.draw.circle(screen, BLACK, eye2, eye_radius)

def draw_food(screen, food, food_type, theme_colors, CELL_SIZE):
    """绘制食物模型"""
    # 根据类型设置颜色
    food_color = theme_colors["food"]
    if food_type == 1:
        food_color = theme_colors["special_food"]
    elif food_type == 2:
        food_color = theme_colors["super_food"]
    
    food_rect = pygame.Rect(food[0] * CELL_SIZE, food[1] * CELL_SIZE, CELL_SIZE, CELL_SIZE)
    pygame.draw.ellipse(screen, food_color, food_rect)  # 使用椭圆形状的食物
    
    # 特殊食物闪烁效果
    if food_type > 0:
        # 使用sin函数创建闪烁效果
        flash_intensity = abs(math.sin(pygame.time.get_ticks() * 0.01)) * 0.5 + 0.5
        # 在食物周围绘制半透明的光环
        s = pygame.Surface((CELL_SIZE * 1.6, CELL_SIZE * 1.6), pygame.SRCALPHA)
        pygame.draw.ellipse(s, (*food_color, int(100 * flash_intensity)), 
                        (0, 0, CELL_SIZE * 1.6, CELL_SIZE * 1.6))
        screen.blit(s, (food[0] * CELL_SIZE - CELL_SIZE * 0.3, food[1] * CELL_SIZE - CELL_SIZE * 0.3))

def draw_items(screen, items, CELL_SIZE, small_font):
    """绘制道具模型"""
    for item in items:
        item_x, item_y, item_type = item
        item_rect = pygame.Rect(item_x * CELL_SIZE, item_y * CELL_SIZE, CELL_SIZE, CELL_SIZE)
        
        # 根据道具类型设置颜色
        if item_type == "speed":  # 加速
            color = ORANGE
            symbol = "+"
        elif item_type == "slow":  # 减速
            color = CYAN
            symbol = "-"
        elif item_type == "double":  # 双倍分数
            color = GOLD
            symbol = "x2"
        elif item_type == "clear":  # 清除障碍
            color = PURPLE
            symbol = "C"
        
        # 绘制道具底色和符号
        pygame.draw.rect(screen, color, item_rect, border_radius=CELL_SIZE // 4)
        item_text = small_font.render(symbol, True, WHITE)
        screen.blit(item_text, (item_rect.centerx - item_text.get_width() // 2, 
                                item_rect.centery - item_text.get_height() // 2))
        
        # 绘制道具光晕
        glow_surf = pygame.Surface((CELL_SIZE * 1.5, CELL_SIZE * 1.5), pygame.SRCALPHA)
        glow_intensity = abs(math.sin(pygame.time.get_ticks() * 0.01)) * 70 + 30
        pygame.draw.rect(glow_surf, (*color, glow_intensity), 
                       (0, 0, CELL_SIZE * 1.5, CELL_SIZE * 1.5), 
                       border_radius=CELL_SIZE//3)
        screen.blit(glow_surf, (item_x * CELL_SIZE - CELL_SIZE * 0.25, 
                               item_y * CELL_SIZE - CELL_SIZE * 0.25))

def draw_obstacles(screen, obstacles, theme_colors, CELL_SIZE):
    """绘制障碍物模型"""
    for obstacle in obstacles:
        obstacle_rect = pygame.Rect(obstacle[0] * CELL_SIZE, obstacle[1] * CELL_SIZE, CELL_SIZE, CELL_SIZE)
        pygame.draw.rect(screen, theme_colors["obstacle"], obstacle_rect)
        # 绘制障碍物的纹理(十字形)
        pygame.draw.line(screen, (*theme_colors["background"], 180),
                        (obstacle[0] * CELL_SIZE + 5, obstacle[1] * CELL_SIZE + CELL_SIZE // 2),
                        (obstacle[0] * CELL_SIZE + CELL_SIZE - 5, obstacle[1] * CELL_SIZE + CELL_SIZE // 2), 2)
        pygame.draw.line(screen, (*theme_colors["background"], 180),
                        (obstacle[0] * CELL_SIZE + CELL_SIZE // 2, obstacle[1] * CELL_SIZE + 5),
                        (obstacle[0] * CELL_SIZE + CELL_SIZE // 2, obstacle[1] * CELL_SIZE + CELL_SIZE - 5), 2)

def draw_game_background(screen, theme_colors, MAP_WIDTH, MAP_HEIGHT, CELL_SIZE):
    """绘制游戏背景和网格"""
    # 绘制背景
    screen.fill(theme_colors["background"])

    # 绘制地图区域网格线
    for x in range(0, MAP_WIDTH, CELL_SIZE):
        pygame.draw.line(screen, theme_colors["grid"], (x, 0), (x, MAP_HEIGHT))
    for y in range(0, MAP_HEIGHT, CELL_SIZE):
        pygame.draw.line(screen, theme_colors["grid"], (0, y), (MAP_WIDTH, y))

def draw_info_panel(screen, theme_colors, MAP_WIDTH, INFO_WIDTH, HEIGHT, score, elapsed_time, speed, 
                   obstacle_count, max_obstacles, current_theme, smooth_animation, active_effects, 
                   main_font, info_font, small_font, LIGHT_BLUE, WHITE, GREEN, RED, ORANGE, CYAN, GOLD):
    """绘制信息面板"""
    # 绘制信息面板背景
    pygame.draw.rect(screen, theme_colors["panel"], (MAP_WIDTH, 0, INFO_WIDTH, HEIGHT))

    # 绘制右侧信息面板边框
    pygame.draw.line(screen, theme_colors["border"], (MAP_WIDTH, 0), (MAP_WIDTH, HEIGHT), 2)

    # 顶部"游戏说明"
    gameinfo_font = pygame.font.SysFont("SimSun, Microsoft YaHei", 32)
    info_title = gameinfo_font.render("游戏说明", True, LIGHT_BLUE)
    screen.blit(info_title, (MAP_WIDTH + INFO_WIDTH//2 - info_title.get_width()//2, 18))

    # 显示分数
    score_text = main_font.render(f"得分: {score}", True, WHITE)
    screen.blit(score_text, (MAP_WIDTH + 30, 65))

    # 显示存活时长
    minutes = int(elapsed_time // 60)
    seconds = int(elapsed_time % 60)
    time_text = info_font.render(f"存活时间: {minutes:02d}:{seconds:02d}", True, WHITE)
    screen.blit(time_text, (MAP_WIDTH + 30, 110))

    # 显示当前速度
    speed_color = WHITE
    if "speed" in active_effects:
        speed_color = ORANGE
    elif "slow" in active_effects:
        speed_color = CYAN
    speed_text = info_font.render(f"速度: {speed}", True, speed_color)
    screen.blit(speed_text, (MAP_WIDTH + 30, 145))

    # 显示障碍物数量
    obstacle_text = info_font.render(f"障碍物: {obstacle_count}/{max_obstacles}", True, WHITE)
    screen.blit(obstacle_text, (MAP_WIDTH + 30, 180))

    # 显示当前主题
    theme_text = info_font.render(f"主题: {current_theme}", True, LIGHT_BLUE)
    screen.blit(theme_text, (MAP_WIDTH + 30, 215))

    # 计算当前显示内容的底部位置，用于响应式布局
    current_y = 215  # 从主题显示的位置开始
    
    # 显示平滑动画状态（移到活动效果上方）
    animation_y = current_y + 35
    animation_text = small_font.render(f"平滑动画: {'开启' if smooth_animation else '关闭'}", True, GREEN if smooth_animation else RED)
    screen.blit(animation_text, (MAP_WIDTH + 30, animation_y))
    
    # 更新当前显示内容的底部位置
    current_y = animation_y + 25  # 平滑动画状态下方留出25像素间距
    
    # 显示活动效果
    if active_effects:
        # 在平滑动画状态下方留出一些间距
        effects_y = current_y + 15
        effects_title = info_font.render("活动效果:", True, WHITE)
        screen.blit(effects_title, (MAP_WIDTH + 30, effects_y))
        
        effect_y_offset = effects_y + 30
        for effect, end_time in active_effects.items():
            remaining = max(0, end_time - pygame.time.get_ticks())
            remaining_sec = remaining / 1000
            
            # 根据效果类型显示不同颜色
            if effect == "speed":
                effect_color = ORANGE
                effect_name = "加速"
            elif effect == "slow":
                effect_color = CYAN
                effect_name = "减速"
            elif effect == "double":
                effect_color = GOLD
                effect_name = "双倍分数"
            
            # 闪烁警告即将结束的效果
            if remaining_sec < 3:
                if int(remaining_sec * 2) % 2:
                    effect_color = WHITE
            
            effect_text = info_font.render(f"{effect_name}: {remaining_sec:.1f}s", True, effect_color)
            screen.blit(effect_text, (MAP_WIDTH + 50, effect_y_offset))
            effect_y_offset += 25

def draw_start_screen(screen, MAP_WIDTH, MAP_HEIGHT, selected_font, GREEN, WHITE, LIGHT_BLUE):
    """绘制开始界面"""
    title_font = pygame.font.SysFont(selected_font or pygame.font.get_default_font(), 60)
    title = title_font.render("贪吃蛇", True, GREEN)
    
    # 绘制游戏标题光晕效果
    glow_size = int(abs(math.sin(pygame.time.get_ticks() * 0.001)) * 20) + 10
    glow_surf = pygame.Surface((title.get_width() + glow_size * 2, title.get_height() + glow_size * 2), pygame.SRCALPHA)
    for i in range(glow_size, 0, -3):
        alpha = 5 if i > glow_size//2 else 10
        pygame.draw.rect(glow_surf, (*GREEN, alpha),
                        (glow_size - i, glow_size - i, 
                        title.get_width() + i * 2, title.get_height() + i * 2),
                        border_radius=i//2)
    
    screen.blit(glow_surf, (MAP_WIDTH // 2 - title.get_width() // 2 - glow_size, MAP_HEIGHT // 3 - glow_size))
    screen.blit(title, (MAP_WIDTH // 2 - title.get_width() // 2, MAP_HEIGHT // 3))
    
    main_font = pygame.font.SysFont(selected_font or pygame.font.get_default_font(), 36)
    subtitle = main_font.render("按下空格键开始游戏", True, WHITE)
    screen.blit(subtitle, (MAP_WIDTH // 2 - subtitle.get_width() // 2, MAP_HEIGHT // 2))
    
    # 显示主题选择说明
    info_font = pygame.font.SysFont(selected_font or pygame.font.get_default_font(), 24)
    theme_text = info_font.render("按 1-4 键选择主题", True, LIGHT_BLUE)
    screen.blit(theme_text, (MAP_WIDTH // 2 - theme_text.get_width() // 2, MAP_HEIGHT // 2 + 50))

def draw_pause_screen(screen, MAP_WIDTH, MAP_HEIGHT, main_font, info_font, RED, WHITE):
    """绘制暂停界面"""
    # 半透明背景
    pause_overlay = pygame.Surface((MAP_WIDTH, MAP_HEIGHT), pygame.SRCALPHA)
    pause_overlay.fill((0, 0, 0, 128))
    screen.blit(pause_overlay, (0, 0))
    
    pause_text = main_font.render("暂停", True, RED)
    text_rect = pause_text.get_rect(center=(MAP_WIDTH // 2, MAP_HEIGHT // 2))
    # 添加暂停文本背景
    pygame.draw.rect(screen, (0, 0, 0, 180), 
                   (text_rect.left - 20, text_rect.top - 10, 
                    text_rect.width + 40, text_rect.height + 20),
                   border_radius=10)
    screen.blit(pause_text, text_rect)
    
    # 显示继续提示
    continue_text = info_font.render("按空格键继续", True, WHITE)
    continue_rect = continue_text.get_rect(center=(MAP_WIDTH // 2, MAP_HEIGHT // 2 + 50))
    screen.blit(continue_text, continue_rect)
